package com.ymx.darling.dialect.keygenerator;

import com.ymx.darling.bean.entity.BeanInfo;
import com.ymx.darling.bean.entity.BeanInfoManager;
import com.ymx.darling.bean.entity.FieldInfo;
import com.ymx.darling.bean.entity.id.IdType;
import com.ymx.darling.bean.sql.Statement;
import com.ymx.darling.type.TypeHandler;
import com.ymx.darling.type.TypeHandlerRegister;
import com.ymx.darling.util.ReflectUtil;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 基于jdbc的{@code java.sql.Statement.RETURN_GENERATED_KEYS}的方式返回自增主键
 * @author 爱Java的小于
 */
public class JdbcKeyGenerator implements KeyGenerator {
    @Override
    public void processBefore(List<Object> entityList, Statement statement) {
    }

    @Override
    public void processAfter(List<Object> entityList, Statement statement, PreparedStatement preparedStatement)throws SQLException {
        try (ResultSet generatedKeys = preparedStatement.getGeneratedKeys()) {
            List<Object> primaryKeys = new ArrayList<>();
            BeanInfo beanInfo = BeanInfoManager.getBeanInfo(entityList.get(0).getClass());
            FieldInfo idColumnInfo = beanInfo.getIdColumnInfo();
            TypeHandler<?> idTypeHandler = idColumnInfo.getTypeHandler();
            // 获取id字段的类型转换器
            if (idTypeHandler == null) {
                idTypeHandler = TypeHandlerRegister.getTypeHandler(idColumnInfo.getField().getType());
            }
            // 遍历结果集
            while (generatedKeys.next()) {
                Object idValue = idTypeHandler.getResult(generatedKeys, 1);
                primaryKeys.add(idValue);
            }
            // 将id回填至实体中
            Field idField = idColumnInfo.getField();
            for (int i = 0; i < primaryKeys.size(); i++) {
                ReflectUtil.setValue(idField, entityList.get(i), primaryKeys.get(i));
            }
        }
    }

    @Override
    public IdType getIdType() {
        return IdType.AUTO;
    }
}
